package com.mchat.user.controller;

import com.mchat.exceptions.CommonException;
import com.mchat.proto.PushOffline;
import com.mchat.user.domain.dto.*;
import com.mchat.user.domain.vo.CurrentUserVo;
import com.mchat.user.domain.vo.LoginUserVO;
import com.mchat.user.domain.vo.UserVO;
import com.mchat.user.service.IUserService;
import com.mchat.util.MailUtil;
import com.mchat.wsserver.MessageUtil;
import com.mchat.wsserver.OnlineUserMap;
import com.mchat.wsserver.enums.ClientOperation;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.mchat.util.Utils.getUid;
import static com.mchat.util.Utils.toProtoTimestamp;

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService userService;

    @GetMapping(value = "/getUsers", produces = MediaType.APPLICATION_NDJSON_VALUE)
    public Flux<UserVO> getUsers(@RequestParam List<Long> ids) {
        return userService.getUsers(ids);
    }

    @GetMapping()
    public Mono<UserVO> getUser(@RequestParam Long id) {
        return userService.getUser(id);
    }

    @PostMapping("/register")
    public Mono<LoginUserVO> register(@RequestBody RegisterDTO dto, ServerWebExchange exchange) {
        if (dto.getEmail() == null || dto.getEmail().isEmpty() || dto.getPassword() == null || dto.getPassword().isEmpty() || !MailUtil.isValid(dto.getEmail()))
            return Mono.error(new CommonException("邮箱或密码错误"));
        exchange.getResponse().setStatusCode(HttpStatus.CREATED);
        return userService.register(dto);
    }

    @PostMapping("/login")
    public Mono<LoginUserVO> login(@RequestBody LoginDTO dto) {
        if (dto.getEmail() == null || dto.getPassword() == null || !MailUtil.isValid(dto.getEmail()))
            return Mono.error(new CommonException("邮箱或密码错误"));
        return userService.login(dto);
    }

    @PatchMapping("/update-avatar")
    public Mono<Void> updateAvatar(ServerWebExchange exchange, @RequestBody UserAvatarDTO dto) {
        if (!StringUtils.isBlank(dto.getAvatar())) {
            exchange.getResponse().setStatusCode(HttpStatus.NO_CONTENT);
            return userService.updateAvatar(getUid(exchange), dto.getAvatar());
        }
        return Mono.error(new CommonException("内容为空"));
    }

    @GetMapping("/current")
    public Mono<CurrentUserVo> getCurrentUser(ServerWebExchange exchange) {
        Long uid = getUid(exchange);
        return userService.getCurrentUser(uid);
    }

    @PatchMapping("/update-info")
    public Mono<Long> updateInfo(ServerWebExchange exchange, @RequestBody UserInfoDTO dto) {
        return userService.updateInfo(getUid(exchange), dto);
    }
    @PatchMapping("update-name")
    public Mono<Long> updateName(ServerWebExchange exchange, @RequestParam String name){
        return userService.updateName(getUid(exchange),name);
    }
    @GetMapping(value = "/search", produces = MediaType.APPLICATION_NDJSON_VALUE)
    public Flux<UserVO>search(@RequestParam String keyword){
        return userService.searchUser(keyword);
    }

    @PatchMapping("/reset-password")
    public Mono<Long> resetPwd(@RequestBody ResetPwdDTO dto, ServerWebExchange exchange) {
        String email = dto.getEmail();
        String pwd = dto.getPassword();
        String code = dto.getCode();
        if (MailUtil.isValid(email) && pwd.length() > 0 && code.length() > 0)
            return userService.resetPwd(dto);

        return Mono.error(new CommonException("参数错误"));
    }

    @GetMapping("/renew-token")
    public Mono<String> updateToken(ServerWebExchange exchange) {
        return userService.updateToken(exchange.getAttribute("claims"));
    }
    @PatchMapping("privacy-settings")
    public Mono<Long>updatePrivacy(@RequestBody UserPrivacyDTO dto ,ServerWebExchange exchange){
        if(dto.getProfileVisible()!=null&&dto.getSearchableByEmail()!=null)
            return userService.updatePrivacy(dto,getUid(exchange));
        return Mono.error(new CommonException("参数错误"));
    }

    @GetMapping("/send")
    public void send() {

        ArrayList<Channel> channels = OnlineUserMap.get(100001L);
        if (channels != null) {
            BinaryWebSocketFrame frame = MessageUtil.sendOfflineMessage("登陆凭证过期","你的登陆凭证已过期，请重新登陆");
            for (Channel channel : channels) {
                channel.writeAndFlush(frame.retainedDuplicate());
            }
            frame.release();
        }
    }

}
